package ch8;

/**
 * 使用线程工厂， 以统一的方式为线程的创建、配置做一些动作
 * 在newThread方法中封装线程创建的逻辑
 */

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

public class XThreadFactory implements ThreadFactory {

    final static Logger LOGGER = Logger.getAnonymousLogger();
    private final Thread.UncaughtExceptionHandler ueh;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    // 所创建的线程的线程名前缀
    private final String namePrefix;

    public XThreadFactory(Thread.UncaughtExceptionHandler ueh, String namePrefix) {
        this.ueh = ueh;
        this.namePrefix = namePrefix;
    }

    public XThreadFactory() {
        this(new LoggingUncaughtExceptionHandler(), "thread");
    }

    protected Thread doMakeThread(final Runnable r) {
        return new Thread(r) {
            @Override
            public String toString() {
                // 返回对问题定位更加有益的信息
                ThreadGroup group = getThreadGroup();
                String groupNmae = null == group ? "" : group.getName();
                String threadInfo = getClass().getSimpleName() + "[" + getName() + "," + getId() + ","
                        + groupNmae + "]@" + hashCode();
                return threadInfo;
            }
        };
    }

    /**
     * 在newThread方法中为创建的每个线程统一做如下逻辑处理：
     * 1. 为线程关联UncaughtExceptionHandler
     * 2. 为线程设置一个含义更加具体的有助于问题定位的名称
     * 3. 确保该线程是一个用户线程
     * 4. 确保线程的优先级为正常级别
     * 5. 在线程创建的时候打印相关日志信息
     * 6. 修改toString()方法，使其返回值更有利于问题的定位
     * @param r
     * @return
     */
    @Override
    public Thread newThread(Runnable r) {
        Thread t = doMakeThread(r);
        t.setUncaughtExceptionHandler(ueh);
        t.setName(namePrefix + "-" + threadNumber.getAndIncrement());
        if (t.isDaemon()) {
            t.setDaemon(false);
        }
        if (t.getPriority() != Thread.NORM_PRIORITY) {
            t.setPriority(Thread.NORM_PRIORITY);
        }
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine("new thread created" + t);
        }
        return t;
    }

    static class LoggingUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            // 将线程异常终止的相关信息记录到日志中
            LOGGER.log(Level.SEVERE, t + "terminated:", e);
        }
    }
}
